package org.v2ray.rocket.proxy.widget

import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import androidx.annotation.ColorInt
import androidx.core.animation.doOnEnd
import androidx.core.content.res.use
import androidx.core.graphics.withClip
import org.v2ray.rocket.proxy.R
import kotlin.math.hypot
import kotlin.math.max
import androidx.core.graphics.toColorInt

class MaterialCommonButton @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyle: Int = 0
) : View(context, attrs, defStyle) {

    // 属性
    private var cornerRadius: Float = 24f * resources.displayMetrics.density
    @ColorInt
    private var gradientStartColor: Int = "#79c8ff".toColorInt()
    @ColorInt
    private var gradientEndColor: Int = "#a48df0".toColorInt()
    private var buttonText: String = ""
    @ColorInt
    private var buttonTextColor: Int = Color.WHITE
    private var buttonTextSize: Float = 16f * resources.displayMetrics.scaledDensity

    // 画笔
    private val bgPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val ripplePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.WHITE
        alpha = 80
    }
    private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = buttonTextColor
        textAlign = Paint.Align.CENTER
        textSize = buttonTextSize
    }

    // 水波纹
    private var rippleRadius = 0f
    private var rippleAlpha = 80
    private var rippleX = 0f
    private var rippleY = 0f
    private var isRippling = false

    private val rectF = RectF()
    private val clipPath = Path()

    init {
        context.obtainStyledAttributes(attrs, R.styleable.MaterialCommonButton).use { ta ->
            cornerRadius = ta.getDimension(R.styleable.MaterialCommonButton_cornerRadius, cornerRadius)
            gradientStartColor = ta.getColor(R.styleable.MaterialCommonButton_gradientStartColor, gradientStartColor)
            gradientEndColor = ta.getColor(R.styleable.MaterialCommonButton_gradientEndColor, gradientEndColor)
            buttonText = ta.getString(R.styleable.MaterialCommonButton_buttonText) ?: ""
            buttonTextColor = ta.getColor(R.styleable.MaterialCommonButton_buttonTextColor, buttonTextColor)
            buttonTextSize = ta.getDimension(R.styleable.MaterialCommonButton_buttonTextSize, buttonTextSize)
        }
        textPaint.color = buttonTextColor
        textPaint.textSize = buttonTextSize
        isClickable = true
        isFocusable = true
    }

    @SuppressLint("DrawAllocation")
    override fun onDraw(canvas: Canvas) {
        rectF.set(0f, 0f, width.toFloat(), height.toFloat())
        clipPath.reset()
        clipPath.addRoundRect(rectF, cornerRadius, cornerRadius, Path.Direction.CW)
        canvas.withClip(clipPath) {
            // 渐变背景
            bgPaint.shader = LinearGradient(
                0f, 0f, width.toFloat(), 0f,
                gradientStartColor, gradientEndColor, Shader.TileMode.CLAMP
            )
            drawRoundRect(rectF, cornerRadius, cornerRadius, bgPaint)
            // 水波
            if (isRippling) {
                ripplePaint.alpha = rippleAlpha
                drawCircle(rippleX, rippleY, rippleRadius, ripplePaint)
            }
            // 文字
            if (buttonText.isNotEmpty()) {
                textPaint.color = buttonTextColor
                textPaint.textSize = buttonTextSize
                val fontMetrics = textPaint.fontMetrics
                val baseLine = height / 2f - (fontMetrics.ascent + fontMetrics.descent) / 2
                drawText(buttonText, width / 2f, baseLine, textPaint)
            }
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                startRipple(event.x, event.y)
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                endRipple()
            }
        }
        return super.onTouchEvent(event)
    }

    private fun startRipple(x: Float, y: Float) {
        rippleX = x
        rippleY = y
        val maxRadius = hypot(
            max(x, width - x),
            max(y, height - y)
        )
        val animator = ValueAnimator.ofFloat(0f, maxRadius).apply {
            setDuration(500)
            addUpdateListener {
                rippleRadius = it.animatedValue as Float
                rippleAlpha = (80 * (1 - it.animatedFraction)).toInt()
                isRippling = true
                invalidate()
            }
            doOnEnd {
                isRippling = false
                invalidate()
            }
        }
        animator.start()
    }

    private fun endRipple() {
        isRippling = false
        invalidate()
    }

    // 公开方法支持代码设置
    fun setCornerRadius(radius: Float) {
        cornerRadius = radius
        invalidate()
    }

    fun setGradientColors(@ColorInt startColor: Int, @ColorInt endColor: Int) {
        gradientStartColor = startColor
        gradientEndColor = endColor
        invalidate()
    }

    fun setButtonText(text: String) {
        buttonText = text
        invalidate()
    }

    fun setButtonTextColor(@ColorInt color: Int) {
        buttonTextColor = color
        textPaint.color = color
        invalidate()
    }

    fun setButtonTextSize(sizeSp: Float) {
        buttonTextSize = sizeSp * resources.displayMetrics.scaledDensity
        textPaint.textSize = buttonTextSize
        invalidate()
    }
} 